﻿#include "graphicsscene.h"
#include <QGraphicsTextItem>
#include <QFont>
#include <QTimer>
#include <QTime>
#include <QDebug>
#include <QElapsedTimer>
#include <QRandomGenerator>
#include <QGraphicsBlurEffect>
#include "block.h"
#include "blockgroup.h"
#include "blockgroupmove.h"

GraphicsScene::GraphicsScene(QObject *parent) : QGraphicsScene(parent)
{
    scene_init();

    speed = 1;

    stand_timer = new QTimer(this);
    stand_timer->setInterval(1000);
    connect(stand_timer, &QTimer::timeout, [this]{
        int time = elapsedTimer->elapsed() / 1000;
        int sec = time % 60;
        int min = (time / 60) % 60;
        int hour = (time / 60) % 24;

        time_item->setPlainText(QTime(hour, min, sec).toString("hh:mm:ss"));

//        nextBlockGroup->newShape();
    });

    elapsedTimer = new QElapsedTimer();


    game_timer = new QTimer(this);
    connect(game_timer, &QTimer::timeout, [this]{
        next_block();
    });

    nextBlockGroup = new BlockGroup(QPointF(580, 60) );
    addItem(nextBlockGroup);

    currentBlockGroup = new BlockGroupMove(QPointF(220, 30));
    addItem(currentBlockGroup);

    connect(currentBlockGroup, &BlockGroupMove::need_next_shape, this, &GraphicsScene::clear_full_rows);
}

void GraphicsScene::scene_init()
{
    QPointF topleft(-1, -1);
    QPointF topright(401, -1);
    QPointF bottomleft(-1, 811);
    QPointF bottomright(401, 811);

//    auto m_topLine = this->addLine(QLineF(topleft, topright), QPen(Qt::NoPen));
    auto m_leftLine = this->addLine(QLineF(topleft, bottomleft), QPen(Qt::NoPen));
    auto m_buttomLine = this->addLine(QLineF(topright, bottomright), QPen(Qt::NoPen));
    auto m_rightLine = this->addLine(QLineF(bottomleft, bottomright), QPen(Qt::NoPen));

//    m_topLine->setPen(QPen(QColor(255,255,255)));
//    m_leftLine->setPen(QPen(QColor(255,255,255)));
//    m_buttomLine->setPen(QPen(QColor(255,255,255)));
//    m_rightLine->setPen(QPen(QColor(255,255,255)));
//    this->setBackgroundBrush(QColor("#444693"));                        //背景
//    this->addRect(-20,-20,440,850,QPen(Qt::NoPen),QBrush("#2a5caa"));   //外框
//    this->addRect(0,0,400,810,QPen(Qt::NoPen),QBrush("#1a2933"));       //内框

//    //网格线
//    for (int i = 0; i < 20; ++i) {
//        this->addLine(0,10+i*40,400,10+i*40,QPen("#102b6a"));
//    }
//    for (int i = 0; i < 10; ++i) {
//        this->addLine(i*40,0,i*40,810,QPen("#102b6a"));
//    }

    //技术统计栏
    QFont font_title("Calibri", 10, QFont::Bold);
    QFont font_sub("Calibri", 15);

    set_text("Player", QPointF(-230,-20), font_title);
    player_item = set_text("007", QPointF(-230,0), font_sub);

    set_text("Time", QPointF(-230,30), font_title);
    time_item = set_text("00:00:00", QPointF(-230,50), font_sub);

    set_text("Score", QPointF(-230,80), font_title);
    score_item = set_text("0", QPointF(-230,100), font_sub);

    //下一个方块
    set_text("NEXT", QPointF(450,-20), font_sub);

    this->setSceneRect(-250, -50, 900, 900);

}

QGraphicsTextItem *GraphicsScene::set_text(QString text, QPointF pos, QFont font, QColor color)
{
    QGraphicsTextItem *item = this->addText(text, font);
    item->setPos(pos);
    item->setDefaultTextColor(color);
    return item;
}

void GraphicsScene::next_block()
{
    int n = QRandomGenerator::global()->bounded(7);
//    qDebug()<<"next block:"<<n;
}

void GraphicsScene::setSpeed(int value)
{
    speed = value;
    game_timer->setInterval(1000 / speed);
}

void GraphicsScene::game_start()
{
    stand_timer->start();
    elapsedTimer->start();

    setSpeed(1);
    game_timer->start();

    auto item_list = this->items(0, -80, 400, 890, Qt::ContainsItemShape, Qt::AscendingOrder);
    foreach (auto item, item_list) {
        Block *block = static_cast<Block *>(item);
        this->removeItem(block);
        block->deleteLater();
    }

    nextBlockGroup->newShape();
    currentBlockGroup->game_start();
}

/*
 * @Brief:  清除满行
 * @Detail: 做了个动画效果
 */
void GraphicsScene::clear_full_rows()
{
    QList<int> full_row_list;                   //记录满行的行号

    for (int i = 0; i < 20; ++i) {
        auto item_list = this->items(0, 10 + i*40, 400, 40, Qt::ContainsItemShape, Qt::AscendingOrder);
//        qDebug()<<"i="<<i<<item_list.count();
        //TODO 满行计算不准
        if(item_list.count() >= 10){
            //遍历列表删除小方块
            foreach (auto item, item_list) {
                //模糊效果，先放大再缩小
                Block *block = static_cast<Block *>(item);
                QGraphicsBlurEffect *blurEffect = new QGraphicsBlurEffect;
                block->setGraphicsEffect(blurEffect);
                QPropertyAnimation *animation = new QPropertyAnimation(block, "scale");
                animation->setDuration(250);
                animation->setEasingCurve(QEasingCurve::OutBounce);
                animation->setStartValue(4);
                animation->setEndValue(0.25);
                animation->start(QAbstractAnimation::DeleteWhenStopped);
                connect(animation, &QPropertyAnimation::finished, block, &Block::deleteLater);
            }
//            m_mediaPlayer->play();
            //记录满行的行地址
            full_row_list.append(i);
        }
    }
//    qDebug()<<"full_row_list"<<full_row_list;

    if(!full_row_list.isEmpty()) {
        //等待所有的小正方形都销毁后再将上方的小正方形向下移动
        QTimer::singleShot(300, [this, full_row_list]{
            for (int i = 0; i < full_row_list.count(); ++i) {
                auto item_list = this->items(0, 10, 400, full_row_list.at(i)*40, Qt::ContainsItemShape, Qt::AscendingOrder);
//                qDebug()<<"移动"<<item_list.count();
                foreach (auto item, item_list) {
                    item->moveBy(0, 40);
                }
            }
//            // 更新分数
//            updateScore(m_rowList.count());

            currentBlockGroup->copyShape(nextBlockGroup);
            nextBlockGroup->newShape();
        });
    } else {  //直接创建新的方块组
        currentBlockGroup->copyShape(nextBlockGroup);
        nextBlockGroup->newShape();
    }
}

void GraphicsScene::drawForeground(QPainter *painter, const QRectF &rect)
{
    Q_UNUSED(rect)

    painter->setBrush(QBrush("#444693"));
    painter->setPen(QPen(Qt::NoPen));
    painter->drawRect(-20, -100, 440, 80);

    painter->setBrush(QBrush("#2a5caa"));
    painter->drawRect(-20, -20, 440, 20);
}

/*
 * @Brief:  绘制背景
 */
void GraphicsScene::drawBackground(QPainter *painter, const QRectF &rect)
{
    painter->setBrush(QBrush("#444693"));
    painter->setPen(QPen(Qt::NoPen));
    painter->drawRect(rect);

    painter->setBrush(QBrush("#2a5caa"));
    painter->drawRect(-20,-20,440,850);     //外框

    painter->setBrush(QBrush("#1a2933"));
    painter->drawRect(0,0,400,810);         //内框

    //网格线
    painter->setPen(QPen("#102b6a"));
    for (int i = 0; i < 20; ++i) {
        painter->drawLine(0, 10+i*40, 400, 10+i*40);
    }
    for (int i = 0; i < 10; ++i) {
        painter->drawLine(i*40, 0, i*40, 810);
    }

    //技术统计栏
    painter->setPen(QPen(Qt::NoPen));
    painter->setBrush(QBrush("#2a5caa"));
    painter->drawRect(-240,-20,200,160);
//    this->addRect(-240,-20,200,160,QPen(Qt::NoPen),QBrush("#2a5caa"));

    //下一个方块
    painter->drawRect(440,-20,200,160);
//    QFont font_sub("Calibri", 15);
//    painter->setPen(QPen("#102b6a"));
//    painter->setFont(font_sub);
//    painter->drawText(QPointF(450,-20), "NEXT");
//    this->addRect(440,-20,200,160,QPen(Qt::NoPen),QBrush("#2a5caa"));
//    set_text("NEXT", QPointF(450,-20), font_sub);
}
